import {ScannerResult} from "../../types";
import path from "path";
import fs from "fs-extra";
import folderSize from "../../utils/folderSize";
import {FormatUtil} from "../../utils/FormatUtil";

// 依赖信息接口
interface PythonDependency {
  name: string;
  version: string;
}

/**
 * 从requirements.txt文件中提取依赖信息
 */
function extractRequirementsDependencies(requirementsContent: string): PythonDependency[] {
  const dependencies: PythonDependency[] = [];
  
  // 分行处理
  const lines = requirementsContent.split('\n');
  
  for (let line of lines) {
    // 去除注释和前后空格
    line = line.split('#')[0].trim();
    if (!line) continue;
    
    // 提取包名和版本 (如 package==1.0.0, package>=1.0.0, package~=1.0.0)
    const match = line.match(/^([a-zA-Z0-9_\-.]+)(?:[<>=~!]+([a-zA-Z0-9_\-.]+))?/);
    if (match) {
      const name = match[1].trim();
      const version = match[2] ? match[2].trim() : '';
      
      dependencies.push({
        name,
        version
      });
    }
  }
  
  return dependencies;
}

/**
 * 从setup.py文件中提取项目信息
 */
function extractSetupInfo(setupContent: string): Record<string, any> {
  const info: Record<string, any> = {};
  
  // 提取名称
  const nameMatch = setupContent.match(/name\s*=\s*["']([^"']+)["']/);
  if (nameMatch) info.name = nameMatch[1];
  
  // 提取版本
  const versionMatch = setupContent.match(/version\s*=\s*["']([^"']+)["']/);
  if (versionMatch) info.version = versionMatch[1];
  
  // 提取描述
  const descMatch = setupContent.match(/description\s*=\s*["']([^"']+)["']/);
  if (descMatch) info.description = descMatch[1];
  
  // 提取作者
  const authorMatch = setupContent.match(/author\s*=\s*["']([^"']+)["']/);
  if (authorMatch) info.author = authorMatch[1];
  
  return info;
}

/**
 * Python项目扫描器
 */
export async function PythonScanner(projectPath: string): Promise<ScannerResult | null> {
  try {
    // 检查可能的Python项目标记文件
    const setupPyPath = path.join(projectPath, 'setup.py');
    const requirementsPath = path.join(projectPath, 'requirements.txt');
    const pipfilePath = path.join(projectPath, 'Pipfile');
    const pyprojectPath = path.join(projectPath, 'pyproject.toml');
    
    // 检查是否是Python项目
    const isPythonProject = await fs.pathExists(setupPyPath) || 
                          await fs.pathExists(requirementsPath) || 
                          await fs.pathExists(pipfilePath) || 
                          await fs.pathExists(pyprojectPath);
    
    if (!isPythonProject) {
      // 检查是否有.py文件
      try {
        const files = await fs.readdir(projectPath);
        const hasPyFiles = files.some(file => file.endsWith('.py'));
        if (!hasPyFiles) return null;
      } catch {
        return null;
      }
    }
    
    // 计算项目大小
    const totalSize = await folderSize.loose(projectPath);
    
    // 尝试获取虚拟环境大小
    let venvSize = 0;
    const possibleVenvs = ['venv', 'env', '.venv', '.env', '.virtualenv'];
    for (const venv of possibleVenvs) {
      const venvPath = path.join(projectPath, venv);
      if (await fs.pathExists(venvPath)) {
        venvSize = await folderSize.loose(venvPath);
        break;
      }
    }
    
    // 项目名称默认为目录名
    let projectName = path.basename(projectPath);
    let version = '未知';
    let description = '';
    let author = '';
    
    // 尝试从setup.py获取项目信息
    if (await fs.pathExists(setupPyPath)) {
      const setupContent = await fs.readFile(setupPyPath, 'utf-8');
      const setupInfo = extractSetupInfo(setupContent);
      
      if (setupInfo.name) projectName = setupInfo.name;
      if (setupInfo.version) version = setupInfo.version;
      if (setupInfo.description) description = setupInfo.description;
      if (setupInfo.author) author = setupInfo.author;
    }
    
    // 提取依赖
    let dependencies: PythonDependency[] = [];
    if (await fs.pathExists(requirementsPath)) {
      const requirementsContent = await fs.readFile(requirementsPath, 'utf-8');
      dependencies = extractRequirementsDependencies(requirementsContent);
    }
    
    return {
      projectName,
      basicInfo: [
        {"名称": projectName},
        {"类型": "Python"},
        {"路径": projectPath},
        {"大小": FormatUtil.formatFileSize(totalSize)},
        {"虚拟环境大小": FormatUtil.formatFileSize(venvSize)},
        {"描述": description},
        {"版本": version},
        {"作者": author},
        {"依赖数量": dependencies.length},
      ],
      mores: [
        {
          title: "依赖",
          type: "table",
          list: dependencies.map(dep => ({
            name: dep.name,
            version: dep.version || '未指定版本'
          }))
        }
      ]
    };
  } catch (error) {
    console.error(`扫描 Python 项目失败: ${projectPath}`, error);
    return null;
  }
} 